<?php

namespace App\Http\Services;

use App\Http\Model\Hint;
use App\Lib\Publisher;
use App\Lib\XFYunVoice;

class VoiceServices extends CommonServices
{
    protected $xfYumVoiceInstance;

    protected $voiceRule = [];

    // 性别类型
    protected $genderType = [
        0 => 'female',// 女性
        1 => 'male',// 男性
    ];

    // 年龄类型
    protected $ageType = [
        0 => 'middle',// 中年
        1 => 'child',// 小孩
        2 => 'old',// 老人
    ];

    public function __construct()
    {
        $this->xfYumVoiceInstance = XFYunVoice::getInstance();
        $this->xfYumVoiceInstance->requestData = $this->requestData;

        $this->voiceRule = config('voice_rule') ?? [];
    }

    /**
     * 获取音频文案描述
     * */
    public function audioDescribe()
    {
        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $arrayRandKeys = array_rand($this->voiceRule['audio_describe'], 20);

        foreach ($arrayRandKeys as $value) {
            $data[] = $this->voiceRule['audio_describe'][$value];
        }

        return compact('code', 'msg', 'data');
    }

    /**
     * 性别年龄 鉴权
     * */
    public function ageGenderAuthorization()
    {
        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $data = $this->xfYumVoiceInstance->sexAgeAuthorization();

        return compact('code', 'msg', 'data');
    }

    /**
     * 性别年龄 分析
     * */
    public function ageGenderAnalysis()
    {
        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $data = [];

        do {
            $this->I('audio_file', '上传音频', 'array', true, '音频不能为空');

            $variables = [];
            $checkParams = $this->check($this->requestData, $variables); //校验数据
            extract($checkParams);
            if ($code !== Hint::SUCCESS) {
                break;
            }
            extract($variables); //数组参数化

            $audioFileName = $this->requestData['audio_file']['tmp_name'] ?? '';
            if (empty($audioFileName)) {
                $code = Hint::ERR_PARAMS_CHECK_FAIL;
                $msg = Hint::getErrCodeMsg($code);
                break;
            }

            $execScriptData = $this->execScript();
            $responseDataAnalysis = $this->responseDataAnalysis($execScriptData);
            if ($responseDataAnalysis['code'] !== $code) {
                $code = $responseDataAnalysis['code'];
                $msg = $responseDataAnalysis['msg'];
                $data = $responseDataAnalysis['data'];
                break;
            }

            $data = $responseDataAnalysis['data'];

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 执行脚本
     * */
    protected function execScript($execLimit = 0)
    {
        $execLimit++;// 默认累加

        if ($execLimit > 3) {
            return '';
        }

        // 访问文件名
        $kdxfFile = '';

        // PHP_OS php自带的一个内置常量，返回的是服务器端的操作系统标示，值为（WINNT，WIN32等）
        $uName = strtoupper(substr(PHP_OS, 0, 3));
        switch ($uName) {
            case 'LIN':// Linux
                $kdxfFile = 'kdxf-linux-amd64';
                break;
            case 'DAR':// mac
                $kdxfFile = 'kdxf-osx-amd64';
                break;
            case 'WIN':// windows
                $kdxfFile = '';
                break;
            default:
                break;
        }

        $publicPath = base_path() . '/public/';
        if (empty($kdxfFile) or !file_exists($publicPath . $kdxfFile)) {
            return '';
        }

        // 执行命令
        exec($publicPath . $kdxfFile . ' -a ' . $this->requestData['audio_file']['tmp_name'], $output, $returnVar);

        $output = $output[0] ?? '';

        if (empty($output) or strstr($output, 'timeout') or !strstr($output, 'age')) {
            $output = $this->execScript($execLimit);
        }

        return $output;
    }

    /**
     * 相应数据解析
     * */
    protected function responseDataAnalysis($execScriptData)
    {
        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $data = [
            'voice_data' => [],
            'timbre' => [ // 音色
                'evaluation' => '外星音？',// 音色评价
                'label' => 1,// 音色标签（移动端对应卡片颜色）
            ],
            'star_rating' => 10,// 星评级
            'chatting_Number' => 1000000,// 可聊人数
            'best_mate' => [],
        ];

        do {
            // 脚本数据 为空则默认
            if (empty($execScriptData)) {
                break;
            }

            json_decode($execScriptData);
            if (json_last_error() != JSON_ERROR_NONE) {
                $code = Hint::ERR_NORMAL;
                $msg = Hint::getErrCodeMsg($code);
                break;
            }
            $execScriptData = json_decode($execScriptData, true);
            $data['voice_data'] = $execScriptData;

            if (!array_key_exists('age', $execScriptData) or !array_key_exists('gender', $execScriptData)) {
                $code = Hint::ERR_PARAMS_CHECK_FAIL;
                $msg = '数据解析失败.';
                break;
            }

            // 性别
            $genderType = $this->genderType[$execScriptData['gender']['gender_type']];
            $genderCoefficientValue = round($execScriptData['gender'][$genderType], 2) * 100;// 性别系数值
            $genderIndex = '';
            foreach ($this->voiceRule['coordinate']['gender_coefficient'] as $key => $value) {
                if ($genderCoefficientValue >= $value[0] and $genderCoefficientValue <= $value) {
                    $genderIndex = $key;
                    break;
                }
            }

            // 年龄
            $ageType = $this->ageType[$execScriptData['age']['age_type']];
            $ageCoefficientValue = round($execScriptData['age'][$ageType], 2) * 100;// 年龄系数值
            $ageIndex = '';
            foreach ($this->voiceRule['coordinate']['age_coefficient'] as $key => $value) {
                if ($ageCoefficientValue > $value[0] and $ageCoefficientValue <= $value) {
                    $ageIndex = $key;
                    break;
                }
            }

            if ($genderIndex === '' or $ageIndex === '') {
                $code = Hint::ERR_PARAMS_CHECK_FAIL;
                $msg = '数据解析失败!';
                break;
            }

            // index 下标查找数据
            $evaluation = $this->voiceRule['coordinate']['audio_desc'][$ageType][$genderIndex][$genderType][$ageIndex];
            $data['timbre'] = [ // 音色
                'evaluation' => $evaluation,// 音色评价
                'label' => $this->voiceRule['coordinate']['audio_label'][$evaluation] ?? 1,// 音色标签（移动端对应卡片颜色）
            ];
            // $data['star_rating'] = $this->voiceRule['coordinate']['audio_desc'][$ageType][$genderIndex]['star'];// 星评级
            $data['star_rating'] = mt_rand(5, 10);// 星评级
            $starMin = $data['star_rating'] * 100000;
            $starMax = (($data['star_rating'] + 1) * 100000) - 1;
            $data['chatting_Number'] = mt_rand($starMin, $starMax);// 可聊人数

            $defaultMate = '萝莉音';// 默认男性伴侣音 匹配
            if ($genderType == 'female') {
                $defaultMate = '正太音';
            }
            // 最佳伴侣
            $bestMate = $this->voiceRule['coordinate']['best_meta'][$evaluation] ?? $this->voiceRule['coordinate']['best_meta'][$defaultMate];
            foreach ($bestMate as $value) {
                $data['best_mate'][] = [
                    'evaluation' => $value,
                    'label' => $this->voiceRule['coordinate']['audio_label'][$value] ?? 1,
                ];
            }

        } while (false);

        return compact('code', 'msg', 'data');
    }
}